
// 参考文档链接: https://nodejs.org/dist/latest-v12.x/docs/api/

// 全局对象 console.log
console.log("hello my first node.js");
console.log("Current excute path: " + __dirname);
console.log("Current excute fileName: " + __filename);

// 延时 3000 ms (计时器)
/*
setTimeout(() => {
    console.log("3 seconds passed!");
}, 3000);
*/

// 定时器循环每隔 2000 ms执行
/*
var timeVal = 0;
var timer = setInterval(function() {
    timeVal += 2;
    console.log(timeVal + " seconds passed!");

    if (timeVal > 4) {
        console.log("timer will be killed!");
        clearInterval(timer);
    }
}, 2000);
*/

// 定义函数
/*
function sayHi() {
    console.log("Hi ^_^!");
}

var sayBye = function(argVal) {
    console.log("Bye ^_^! " + argVal);
}

function callFunction(funName, val) {
    console.log("-------- Use callFunction to excute the func begin----------");
    funName(val);
    console.log("-------- Use callFunction to excute the func end----------");
}

sayHi();
sayBye("Johnny");
callFunction(sayBye, "Peter");
callFunction(function(val2) {
    console.log("this func be called! val2: " + val2);
}, 'Kobe');
*/


//--------------------------------------------------------------
// use diy modules. (get the object.)
// var stuff = require('./getCount.js');

// console.log(stuff.counter(['1','2']));
// console.log(stuff.adder(5, 999));
// console.log(stuff.subber(5, 999));
// console.log(stuff.pi);
//--------------------------------------------------------------


//--------------------------------------------------------------
// signals and slots.
// var events = require('events');     // one of the node.js core module about events
// var util = require('util');         // one of the node.js core module about tool

// var myEmitter = new events.EventEmitter();

// myEmitter.on('someEvent', function(message) {
//     console.log(message);
// })

// myEmitter.emit('someEvent', 'we sent the Event message!!!');

// // an object using. (like signals and slot in QT)
// var Person = function(name) {
//     this.name = name;
// }

// // The Person class inherits events.EventEmitter class.
// util.inherits(Person, events.EventEmitter);

// var Johnny = new Person('Johnny');
// var Zhangsan = new Person('Zhangsan');
// var Lisi = new Person('Lisi');

// var persons = [Johnny, Zhangsan, Lisi];
// persons.forEach(function(person){
//     // binding the signals and slots.  (just like connect() in Qt)
//     person.on('speak', function(message) {
//         console.log(person.name + " said: " + message);
//     });
// })

// Johnny.emit('speak', 'Hi! I am Johnny');
// Zhangsan.emit('speak', 'Hi! I am Zhangsan');
// Lisi.emit('speak', 'Hi! I am Lisi');
//--------------------------------------------------------------


//--------------------------------------------------------------
// // IO and file system
// var fs = require('fs');

// write the sting into the file.
// fs.writeFileSync("readtest.txt", "WRITE CONTENT!!!", "utf8");

// if the file size is too big, will block here
// var readMeContent = fs.readFileSync("readtest.txt", "utf8");

// will not block here. cuz node.js will new a event thread, when thread excute finished, the result will sent back to the main thread.
// var readMeContent_1 = fs.readFile("readtest.txt", "utf8", function(err, data) {
//     console.log(data);
// })

// console.log(readMeContent);
// console.log("finished!");

// // create the file (sync)
// fs.writeFileSync("test.txt", "", "utf8");

// // delete file (asyn)
// fs.unlink("test.txt", function() {
//     console.log("delete the file finished!");
// })

// // create directory (async)
// fs.mkdir("stuff", function() {
//     console.log("mkdir stuff finished!");
// })

// // delete the directory (async)
// fs.rmdir("stuff", function() {
//     console.log("remove the directory!");
// })

//--------------------------------------------------------------

//--------------------------------------------------------------
// using stream. (buffer, when file size is bigger than RAM)
// var fs = require('fs');


// var myWriteStream = fs.createWriteStream(__dirname + "/readtest.txt");
// var writeData = "hello world! (write data)";
// myWriteStream.write(writeData);
// myWriteStream.end();
// myWriteStream.on('finish', function() {
//     console.log('wirite finished !!');
// })

// var myReadStream = fs.createReadStream(__dirname + '/readtest.txt', 'utf8');
// var strData = "";
// myReadStream.on('data', function(chunk) {
//     // console.log("new chunk received!");
//     // console.log(chunk);
//     strData += chunk;
// })

// myReadStream.on('end', function() {
//     console.log(strData);
// })
//--------------------------------------------------------------

//--------------------------------------------------------------
// using encryption function.
var cryptoModule = require('crypto');
var fsModule = require('fs');
var zlibModule = require('zlib');

var password = new Buffer(process.env.PASS || 'password');
var encryptStream = cryptoModule.createCipher('aes-256-cbc', password);

var gzip = zlibModule.createGzip();
var readStream = fsModule.createReadStream(__dirname + "/readtest.txt");
var writeSteam = fsModule.createWriteStream(__dirname + "/out.gz");

// this will be like  `ls -lrt | grep A | grep B | grep C`
readStream                      // read
    .pipe(encryptStream)        // encrypts
    .pipe(gzip)                 // compress
    .pipe(writeSteam)           // write it to out file.
    .on('finish', function() {  // all done.
        console.log("done!");
    })

// wait 3 seconds!
setTimeout(() => {
    console.log("3 seconds passed!");
}, 3000);

var decryptStream = cryptoModule.createDecipher('aes-256-cbc', password);
var gunzip = zlibModule.createGunzip();
var readZipStream = fsModule.createReadStream(__dirname + "/out.gz");

readZipStream                   // read
    .pipe(gunzip)               // uncompress
    .pipe(decryptStream)        // decrypts
    .pipe(process.stdout)       // write to terminal stdout
    .on('finish', function() {  // done
        console.log("done!!");
    })

//--------------------------------------------------------------